package org.example.netty.EncodeDecode;

import java.io.File;
import java.io.RandomAccessFile;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;

public class CharsetStu {
    public static void main(String[] args) throws Exception {
        String inputFile = "NioTest13_In.txt";
        String outputFile = "NioTest13_out.txt";
        //  创建随机访问文件，并以读写模式打开。
        // RandomAccessFile  是用于访问文件内容的类，它既可以读也可以写。
        // FileOutputStream RandomAccessFile 都可以获取 FileChannel
        // 区别 在于 RandomAccessFile 可以定位到文件的任意位置，而 FileOutputStream 只能从头开始写入。
        // 读写参数不同
        RandomAccessFile inputRandomAccessFile = new RandomAccessFile(inputFile, "r");
        RandomAccessFile outputRandomAccessFile = new RandomAccessFile(outputFile, "rw");

        long inputLength = new File(inputFile).length();
        // 获取文件通道,用于读取文件内容。
        FileChannel inputFileChannel = inputRandomAccessFile.getChannel();
        FileChannel outputFileChannel = outputRandomAccessFile.getChannel();
        // 映射文件到内存，可以直接操作内存中的数据。
        // 映射模式有三种：READ_ONLY, READ_WRITE, PRIVATE
        MappedByteBuffer inputData = inputFileChannel.map(FileChannel.MapMode.READ_ONLY, 0, inputLength);
        // 创建字符集编码和解码器。
        // Charset 类表示字符集，它是一个抽象类。
        // 它提供了静态方法 forName() 用于获取指定名称的字符集对象。
        // 从文件中读取到的如果是GBK,ISO-8859-1等编码，使用utf-8则会出现乱码，需要使用相应的字符集编码和解码器。
        Charset charset = Charset.forName("utf-8");
        // CharsetDecoder 类用于将字节解码为字符。
        // CharsetEncoder 类用于将字符编码为字节。
        // Charset 类提供了 newDecoder() 和 newEncoder() 方法用于创建字符集编码器和解码器。
        CharsetDecoder decoder = charset.newDecoder();
        CharsetEncoder encoder = charset.newEncoder();
        // 将字节解码为字符，然后将字符编码为字节。
        // CharBuffer 类用于表示字符缓冲区。
        // ByteBuffer 类用于表示字节缓冲区。
        // decode() 方法用于将字节解码为字符，encode() 方法用于将字符编码为字节。
        // decode() 方法返回一个 CharBuffer 对象，encode() 方法返回一个 ByteBuffer 对象。
        // decode() 方法有两个重载版本，一个接受 ByteBuffer 对象作为参数，另一个接受 CharBuffer 对象作为参数。
        // encode() 方法也有两个重载版本，一个接受 CharSequence 对象作为参数，另一个接受 CharBuffer 对象作为参数。
        // 这里我们使用 decode() 方法将字节解码为字符，然后使用 encode() 方法将字符编码为字节。
        // decode() 方法接受 ByteBuffer 对象作为参数，返回一个 CharBuffer 对象。
        // encode() 方法接受 CharSequence 对象作为参数，返回一个 ByteBuffer 对象。

        CharBuffer charBuffer = decoder.decode(inputData);
        ByteBuffer outputData = encoder.encode(charBuffer);

        outputFileChannel.write(outputData);

        inputRandomAccessFile.close();
        outputRandomAccessFile.close();
    }
}